
#include <iostream>
#include <fstream>

#include <Logging.h>
#include <CommandLineProcess.h>
#include <CompressArgumentHandler.h>
#include <DecompressArgumentHandler.h>
#include <CompressionProcess.h>
#include <LoggingArgumentHandler.h>
#include <time.h>

using logging::Logger;
using logging::LoggerFactory;
using logging::Level;

using CommandLineProcess::CommandLineProcessor;
using CommandLineProcess::ArgumentHandler;
using CommandLineProcess::Tag;

using namespace providers;
using namespace std;
using namespace handlers;

// signature: "ACMC" (0x434D4341, intel byte order)
const int g_Signature = 0x434D4341;


int main(int argc, const char** argv) {

        int start = time(NULL);
        char segsStr[21]; // enough to hold all numbers up to 64-bits
    
	// Default to INFO.
	LoggerFactory::getInstance().setApplicationLevel(logging::INFO);

	//Creates the command line processor, and registers all posible actions
	CommandLineProcessor cmdLineProcessor(cout);

	//Compress Handler
	string action = "-c";
	Tag compTag(action,false);
	string desc = "Compress the corresponding file.";
	CompressArgumentHandler compArg(compTag,desc);
	cmdLineProcessor.registerArgumentHandler(compArg);

	//Decompress Handler
	string action2 = "-x";
	Tag decompTag(action2,false);
	string desc2 = "Decompress the corresponding file.";
	DecompressArgumentHandler decompArg(decompTag,desc2);
	cmdLineProcessor.registerArgumentHandler(decompArg);

	string loggingTagName = "-logLevel";
	Tag loggingTag(loggingTagName, false);
	string loggingDesc = "Logging level configurator.";
	LoggingArgumentHandler loggingArgHandler(loggingTag, loggingDesc);
	cmdLineProcessor.registerArgumentHandler(loggingArgHandler);

        Logger& theRootLogger = LoggerFactory::getInstance().getRootLogger();
        //Process the request and if it's ok it proceeds with the func
	if (cmdLineProcessor.processArguments(argc, argv)){
		theRootLogger.log(logging::INFO, "Starting application. Running processes now.");
		CompressionCommand* command = CompressionProcessProvider::createCompressionCommand();
		command->doCompressionProcess();
		delete command;
		theRootLogger.log(logging::INFO, "Processes finished. Closing application.");
	}
        std::string timerStr = "Time: ";
        sprintf(segsStr, "%d", time(NULL) - start);
        theRootLogger.log(logging::INFO, timerStr + segsStr + "s");
	return 0;
}
